package server_service

/**
* @author aFun
* @data 2025/4/11 08:39
* @email: afunaaa222@163.com / 1030935903
* @address: Guangdong University of Technology, China
 */

import (
	"camp_lucky_draw/entity"
	"camp_lucky_draw/server"
	"camp_lucky_draw/server/data"
	"encoding/json"
	"errors"
	"github.com/streadway/amqp"
)

func Do_get_floor_rewards(role *entity.Role, Args map[string]interface{}) error {
	tx := server.DB.Begin()
	if tx.Error != nil {
		return tx.Error
	}
	err := do_check_floor_rewards(
		role, Args,
		check_is_open,
		check_lev,
		check_can_floor_reward,
		check_cur_floor,
		check_is_max_quantity,
		gain_floor_rewards,
		update_fr)
	if err != nil {
		tx.Rollback()
		return err
	}

	if err = tx.Save(&role).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return err
}

func do_check_floor_rewards(role *entity.Role, Args map[string]interface{}, checks ...CheckFunc) error {
	for _, check := range checks {
		if err := check(role, Args); err != nil {
			return err
		}
	}
	return nil
}

func check_can_floor_reward(role *entity.Role, Args map[string]interface{}) error {
	ld := role.Lucky_draw
	if ld.Prev_change == 0 {
		// 没抽过奖 不给领取
		return errors.New("没扭蛋过，没有奖励哦")
	}
	return nil
}

func check_cur_floor(role *entity.Role, Args map[string]interface{}) error {
	argsFloor := Args["floor"].(int8)
	CurFloor := role.Lucky_draw.Cur_floor
	if argsFloor != CurFloor {
		return errors.New("层数对不上")
	}
	return nil
}

func check_is_max_quantity(role *entity.Role, Args map[string]interface{}) error {
	argsFloor := Args["floor"].(int8)
	argsPos := Args["pos"].(int8)
	ld := role.Lucky_draw
	ldRewarded := ld.FloorRewarded
	for _, ldr := range ldRewarded {
		if ldr.Floor == argsFloor && ldr.Pos == argsPos {
			// 读取配置中的最大quantitiy
			FAP := data.FloorAndPos{argsFloor, argsPos}
			Rewards := data.GetFloorRewards[FAP].(map[string]interface{})
			if Rewards["maxQuantity"] != nil {
				maxNum := int32(Rewards["maxQuantity"].(float64))
				curNum := ldr.Num
				if curNum >= maxNum {
					return errors.New("已达到最大领取次数，不能再领取")
				}
			}
			break
		}
	}
	return nil
}

func gain_floor_rewards(role *entity.Role, Args map[string]interface{}) error {
	argsFloor := Args["floor"].(int8)
	argsPos := Args["pos"].(int8)
	FAP := data.FloorAndPos{argsFloor, argsPos}
	Rewards := data.GetFloorRewards[FAP]
	if Rewards == nil {
		return errors.New("不存在的奖励")
	}
	Args["rewards"] = Rewards
	return nil
}

func update_fr(role *entity.Role, Args map[string]interface{}) error {
	argsFloor := Args["floor"].(int8)
	argsPos := Args["pos"].(int8)
	Rewards := Args["rewards"].(map[string]interface{})
	num := int32(Rewards["quantity"].(float64))
	ld := role.Lucky_draw
	// 在Rewarded中找有没有 floor, pos的，有的话则加上去num
	// 没有再创建
	Reward := entity.FloorReward{
		argsFloor, argsPos, num,
	}
	ldRewarded := ld.FloorRewarded
	findFlag := false
	//// 这里有个坑
	//// 这种做法是错的，因为ldr是值拷贝，并不影响原来的值
	//for _, ldr := range ldRewarded {
	//	if ldr.Floor == argsFloor && ldr.Pos == argsPos {
	//		ldr.Num += num
	//		findFlag = true
	//		break
	//	}
	//}
	// 正确做法
	for i := range ldRewarded {
		if ldRewarded[i].Floor == argsFloor && ldRewarded[i].Pos == argsPos {
			ldRewarded[i].Num += num
			findFlag = true
			break
		}
	}
	if !findFlag {
		ldRewarded = append(ldRewarded, Reward)
	}
	// 写回
	ld.FloorRewarded = ldRewarded
	ld.Prev_change = 0
	ld.Cur_floor = 0
	role.Lucky_draw = ld

	// 更新玩家背包 直接插入了 不是重点内容
	item := entity.Item{
		int64(Rewards["itemId"].(float64)),
		int64(Rewards["quantity"].(float64)),
		Rewards["itemName"].(string),
	}
	role.Bags = append(role.Bags, item)

	// 诶这里可以做个邮件系统，用rabbitmq异步发到邮件系统
	ch, _ := server.MQ.Channel()
	defer ch.Close()
	itemQ := entity.ItemForQueue{
		role.ID,
		int64(Rewards["itemId"].(float64)),
		int64(Rewards["quantity"].(float64)),
		Rewards["itemName"].(string),
	}
	body, _ := json.Marshal(itemQ)
	_ = ch.Publish(
		"",
		"rewards_update",
		false,
		false,
		amqp.Publishing{
			ContentType: "application/json",
			Body:        body,
		})
	return nil
}
